from flask import Blueprint, request, jsonify, current_app
from werkzeug.utils import secure_filename
import os
import uuid
from datetime import datetime
from flasgger import swag_from

upload_bp = Blueprint('upload', __name__)

# 允许上传的文件类型
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'webp'}

def allowed_file(filename):
    """检查文件类型是否允许"""
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@upload_bp.route('/upload/image', methods=['POST'])
@swag_from({
    'tags': ['文件上传'],
    'summary': '上传图片',
    'description': '上传单张图片文件，支持 PNG、JPG、JPEG、GIF、WEBP 格式，最大4MB',
    'consumes': ['multipart/form-data'],
    'parameters': [
        {
            'name': 'file',
            'in': 'formData',
            'type': 'file',
            'required': True,
            'description': '要上传的图片文件'
        },
        {
            'name': 'type',
            'in': 'formData',
            'type': 'string',
            'required': False,
            'description': '图片类型：activity=活动图片, venue=场馆图片, banner=轮播图, avatar=用户头像'
        }
    ],
    'responses': {
        200: {
            'description': '上传成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200},
                    'message': {'type': 'string', 'example': '上传成功'},
                    'data': {
                        'type': 'object',
                        'properties': {
                            'filename': {'type': 'string', 'description': '文件名'},
                            'url': {'type': 'string', 'description': '访问URL'},
                            'size': {'type': 'integer', 'description': '文件大小（字节）'}
                        }
                    }
                }
            }
        },
        400: {
            'description': '上传失败'
        }
    }
})
def upload_image():
    """上传图片"""
    try:
        # 检查是否有文件
        if 'file' not in request.files:
            return jsonify({'code': 400, 'message': '没有选择文件'}), 400
        
        file = request.files['file']
        if file.filename == '':
            return jsonify({'code': 400, 'message': '没有选择文件'}), 400
        
        # 检查文件类型
        if not allowed_file(file.filename):
            return jsonify({'code': 400, 'message': '不支持的文件类型'}), 400
        
        # 检查文件大小 (限制为4MB)
        file.seek(0, 2)  # 移动到文件末尾
        file_size = file.tell()
        file.seek(0)  # 重置文件指针
        max_size = 4 * 1024 * 1024  # 4MB
        if file_size > max_size:
            return jsonify({'code': 400, 'message': '文件大小不能超过4MB'}), 400
        
        # 获取图片类型
        img_type = request.form.get('type', 'activity')
        
        # 生成安全的文件名
        filename = secure_filename(file.filename)
        file_ext = filename.rsplit('.', 1)[1].lower()
        unique_filename = f"{uuid.uuid4().hex}.{file_ext}"
        
        # 创建上传目录
        upload_dir = os.path.join(current_app.config.get('UPLOAD_FOLDER', 'uploads'), img_type)
        os.makedirs(upload_dir, exist_ok=True)
        
        # 保存文件
        file_path = os.path.join(upload_dir, unique_filename)
        file.save(file_path)
        
        # 生成访问URL - 只返回相对路径，不包含域名
        file_url = f"/uploads/{img_type}/{unique_filename}"
        
        # 获取文件大小
        file_size = os.path.getsize(file_path)
        
        return jsonify({
            'code': 200,
            'message': '上传成功',
            'data': {
                'filename': unique_filename,
                'url': file_url,
                'size': file_size
            }
        })
        
    except Exception as e:
        current_app.logger.error(f"上传图片失败: {str(e)}")
        return jsonify({'code': 500, 'message': '上传失败'}), 500

@upload_bp.route('/upload/multiple', methods=['POST'])
@swag_from({
    'tags': ['文件上传'],
    'summary': '批量上传图片',
    'description': '一次上传多张图片文件，每个文件最大4MB',
    'consumes': ['multipart/form-data'],
    'parameters': [
        {
            'name': 'files',
            'in': 'formData',
            'type': 'file',
            'required': True,
            'description': '要上传的图片文件（支持多选）'
        },
        {
            'name': 'type',
            'in': 'formData',
            'type': 'string',
            'required': False,
            'description': '图片类型：activity=活动图片, venue=场馆图片, banner=轮播图, avatar=用户头像'
        }
    ],
    'responses': {
        200: {
            'description': '上传成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200},
                    'message': {'type': 'string', 'example': '上传成功'},
                    'data': {
                        'type': 'object',
                        'properties': {
                            'files': {
                                'type': 'array',
                                'items': {
                                    'type': 'object',
                                    'properties': {
                                        'filename': {'type': 'string'},
                                        'url': {'type': 'string'},
                                        'size': {'type': 'integer'}
                                    }
                                }
                            },
                            'success_count': {'type': 'integer'},
                            'failed_count': {'type': 'integer'}
                        }
                    }
                }
            }
        }
    }
})
def upload_multiple():
    """批量上传图片"""
    try:
        files = request.files.getlist('files')
        if not files or all(f.filename == '' for f in files):
            return jsonify({'code': 400, 'message': '没有选择文件'}), 400
        
        img_type = request.form.get('type', 'activity')
        upload_dir = os.path.join(current_app.config.get('UPLOAD_FOLDER', 'uploads'), img_type)
        os.makedirs(upload_dir, exist_ok=True)
        
        uploaded_files = []
        success_count = 0
        failed_count = 0
        
        for file in files:
            if file.filename == '':
                continue
                
            try:
                if not allowed_file(file.filename):
                    failed_count += 1
                    continue
                
                # 检查文件大小 (限制为4MB)
                file.seek(0, 2)  # 移动到文件末尾
                file_size = file.tell()
                file.seek(0)  # 重置文件指针
                max_size = 4 * 1024 * 1024  # 4MB
                if file_size > max_size:
                    failed_count += 1
                    continue
                
                filename = secure_filename(file.filename)
                file_ext = filename.rsplit('.', 1)[1].lower()
                unique_filename = f"{uuid.uuid4().hex}.{file_ext}"
                
                file_path = os.path.join(upload_dir, unique_filename)
                file.save(file_path)
                
                # 生成访问URL - 只返回相对路径，不包含域名
                file_url = f"/uploads/{img_type}/{unique_filename}"
                file_size = os.path.getsize(file_path)
                
                uploaded_files.append({
                    'filename': unique_filename,
                    'url': file_url,
                    'size': file_size
                })
                success_count += 1
                
            except Exception as e:
                current_app.logger.error(f"上传文件 {file.filename} 失败: {str(e)}")
                failed_count += 1
        
        return jsonify({
            'code': 200,
            'message': f'上传完成，成功 {success_count} 个，失败 {failed_count} 个',
            'data': {
                'files': uploaded_files,
                'success_count': success_count,
                'failed_count': failed_count
            }
        })
        
    except Exception as e:
        current_app.logger.error(f"批量上传图片失败: {str(e)}")
        return jsonify({'code': 500, 'message': '上传失败'}), 500 